/*
 * cs5536_io.h
 * some basic access of msr read/write and gpio read/write. 
 * this access function only suitable before the virtual support module(VSM)
 * working for some simple debugs.
 *
 * Author : jlliu <liujl@lemote.com>
 * Date : 07-07-04
 *
 */

#include "TianoCommon.h"
#include "Pci.h"
#include "Cs5536_pci.h"
#include "BonitoReg.h"
#include "ArchDefs.h"

/******************************************************************************/

/*
 * rdmsr : read 64bits data from the cs5536 MSR register
 */
void _rdmsr(UINT32 msr, UINT32 *hi, UINT32 *lo)
{
	UINT32 type = 0x00000;
	UINT32 addr;
	
	addr = (PCI_BUS_CS5536 << 16) | (1 << (PCI_IDSEL_CS5536 + 11) ) | (0 << 8) | 0xf4;
	REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT | EFI_PCI_STATUS_MASTER_TARGET_ABORT;
	REGVAL(BONITO_PCIMAP_CFG) = (addr >> 16) | type;
	*(volatile UINT32 *)PHYS_TO_UNCACHED(BONITO_PCICFG_BASE | (addr & 0xfffc)) = msr;
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT;
    	}
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_TARGET_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_TARGET_ABORT;
    	}

	addr = (PCI_BUS_CS5536 << 16) | (1 << (PCI_IDSEL_CS5536 + 11) ) | (0 << 8) | 0xf8;
	REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT | EFI_PCI_STATUS_MASTER_TARGET_ABORT;
	REGVAL(BONITO_PCIMAP_CFG) = (addr >> 16) | type;
	*lo = *(volatile UINT32 *)PHYS_TO_UNCACHED(BONITO_PCICFG_BASE | (addr & 0xfffc));
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT;
    	}
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_TARGET_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_TARGET_ABORT;
    	}

	addr = (PCI_BUS_CS5536 << 16) | (1 << (PCI_IDSEL_CS5536 + 11) ) | (0 << 8) | 0xfc;
	REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT | EFI_PCI_STATUS_MASTER_TARGET_ABORT;
	REGVAL(BONITO_PCIMAP_CFG) = (addr >> 16) | type;
	*hi = *(volatile UINT32 *)PHYS_TO_UNCACHED(BONITO_PCICFG_BASE | (addr & 0xfffc));
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT;
    	}
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_TARGET_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_TARGET_ABORT;
    	}

	return;	
}

/*
 * wrmsr : write 64bits data to the cs5536 MSR register
 */
void _wrmsr(UINT32 msr, UINT32 hi, UINT32 lo)
{
	UINT32 type = 0x00000;
	UINT32 addr;
	
	addr = (PCI_BUS_CS5536 << 16) | (1 << (PCI_IDSEL_CS5536 + 11) ) | (0 << 8) | 0xf4;
	REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT | EFI_PCI_STATUS_MASTER_TARGET_ABORT;
	REGVAL(BONITO_PCIMAP_CFG) = (addr >> 16) | type;
	*(volatile UINT32 *)PHYS_TO_UNCACHED(BONITO_PCICFG_BASE | (addr & 0xfffc)) = msr;
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT;
    	}
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_TARGET_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_TARGET_ABORT;
    	}

	addr = (PCI_BUS_CS5536 << 16) | (1 << (PCI_IDSEL_CS5536 + 11) ) | (0 << 8) | 0xf8;
	REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT | EFI_PCI_STATUS_MASTER_TARGET_ABORT;
	REGVAL(BONITO_PCIMAP_CFG) = (addr >> 16) | type;
	*(volatile UINT32 *)PHYS_TO_UNCACHED(BONITO_PCICFG_BASE | (addr & 0xfffc)) = lo;
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT;
    	}
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_TARGET_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_TARGET_ABORT;
    	}


	addr = (PCI_BUS_CS5536 << 16) | (1 << (PCI_IDSEL_CS5536 + 11) ) | (0 << 8) | 0xfc;
	REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT | EFI_PCI_STATUS_MASTER_TARGET_ABORT;
	REGVAL(BONITO_PCIMAP_CFG) = (addr >> 16) | type;
	*(volatile UINT32 *)PHYS_TO_UNCACHED(BONITO_PCICFG_BASE | (addr & 0xfffc)) = hi;
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_ABORT;
    	}
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) & EFI_PCI_STATUS_MASTER_TARGET_ABORT) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_OFFSET)) |= EFI_PCI_STATUS_MASTER_TARGET_ABORT;
    	}


	return;	
}
